#include "pch.hpp"
#include "quad.hpp"




Quad::Quad(const int2& pos, const intsize2& size,
		   const float2& texPos, const floatsize2& texSize,
		   const math::color& col)
{
	m_lowerLeft.position.x = static_cast<float>(pos.x);
	m_lowerLeft.position.y = static_cast<float>(pos.y + size.height);
	m_lowerLeft.tex.x = texPos.x;
	m_lowerLeft.tex.y = texPos.y + texSize.height;
	m_lowerLeft.col = col;

	m_upperLeft.position.x = static_cast<float>(pos.x);
	m_upperLeft.position.y = static_cast<float>(pos.y);
	m_upperLeft.tex.x = texPos.x;
	m_upperLeft.tex.y = texPos.y;
	m_upperLeft.col = col;

	m_upperRight.position.x = static_cast<float>(pos.x + size.width);
	m_upperRight.position.y = static_cast<float>(pos.y);
	m_upperRight.tex.x = texPos.x + texSize.width;
	m_upperRight.tex.y = texPos.y;
	m_upperRight.col = col;

	m_lowerRight.position.x = static_cast<float>(pos.x + size.width);
	m_lowerRight.position.y = static_cast<float>(pos.y + size.height);
	m_lowerRight.tex.x = texPos.x + texSize.width;
	m_lowerRight.tex.y = texPos.y + texSize.height;
	m_lowerRight.col = col;
}
///////////////////////////////////////////////////////////////////////////////////////////////////




int2 Quad::pos() const
{
	return int2(static_cast<int>(m_upperLeft.position.x), static_cast<int>(m_upperLeft.position.y));
}
///////////////////////////////////////////////////////////////////////////////////////////////////

intsize2 Quad::size() const
{
	return intsize2(static_cast<int>(m_upperRight.position.x - m_upperLeft.position.x), static_cast<int>(m_upperRight.position.y - m_lowerRight.position.y));
}
///////////////////////////////////////////////////////////////////////////////////////////////////




void Quad::move(const int2& amount)
{
	m_lowerLeft.position.x  += amount.x; m_lowerLeft.position.y  += amount.y;
	m_upperLeft.position.x  += amount.x; m_upperLeft.position.y  += amount.y;
	m_upperRight.position.x += amount.x; m_upperRight.position.y += amount.y;
	m_lowerRight.position.x += amount.x; m_lowerRight.position.y += amount.y;
}
///////////////////////////////////////////////////////////////////////////////////////////////////

void Quad::resize(const rect& r)
{
	move(r.topLeft - pos());
	resize(r.size());
}
///////////////////////////////////////////////////////////////////////////////////////////////////

void Quad::resize(const intsize2& size)
{
	m_lowerLeft.position.y  = m_upperLeft.position.y + size.height;
	m_upperRight.position.x = m_upperLeft.position.x + size.width;
	m_lowerRight.position.x = m_upperLeft.position.x + size.width;
	m_lowerRight.position.y = m_upperLeft.position.y + size.height;
}
///////////////////////////////////////////////////////////////////////////////////////////////////

void Quad::setTex(const float2& pos, const floatsize2& size)
{
	m_upperLeft.tex  = pos;
	m_upperRight.tex = pos + float2(size.width, 0);
	m_lowerRight.tex = pos + float2(size.width, size.height);
	m_lowerLeft.tex  = pos + float2(0, size.height);
}
///////////////////////////////////////////////////////////////////////////////////////////////////

void Quad::setColor(const math::color& col)
{
	m_lowerLeft.col  = col;
	m_upperLeft.col  = col;
	m_upperRight.col = col;
	m_lowerRight.col = col;
}
///////////////////////////////////////////////////////////////////////////////////////////////////




uint32 Quad::numIndices(uint32 numQuads)
{
	return numQuads * 6;
}
///////////////////////////////////////////////////////////////////////////////////////////////////

uint32 Quad::numVertices(uint32 numQuads)
{
	return numQuads * 4;
}
///////////////////////////////////////////////////////////////////////////////////////////////////

void Quad::vertices(const Quads& quads, GuiVertices& vertices)
{
	uint32 numQuads    = static_cast<uint32>(quads.size());
	uint32 numVertices = Quad::numVertices(numQuads);

	if(!numQuads)
		return;

	// This cast works as long as the layout of the quad is not reordered
	// or padded with additional bytes (VERIFY IN UNIT TEST)
	const GuiVertex* tmp = reinterpret_cast<const GuiVertex*>(&quads[0]);

	vertices.resize(numVertices);
	memcpy(&vertices[0], tmp, sizeof(GuiVertex) * numVertices);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
